#ifndef __LOGGER_H__
#define __LOGGER_H__
#include<sstream>
#include<fstream>//文件流 直接使用一个流式运算符写入到文件中
#include"message.h"
#include<iostream>
//单例模式
/*
懒汉式
饿汉式
线程安全的单例模式

把构造函数私有化
提供生成对象的静态方法

单例模式  迭代器模式  简单工厂 抽象工厂  工厂方法  观察者模式  装饰器模式
*/
class Logger
{
private:
    Logger();
    bool m_LoToTerminal;
    bool m_LogToLogFile;
    std::fstream m_logFile;
    LOG_LEVEL m_level;
public:
    static Logger*GetInstance()
    {
        static Logger Logger;
        return &Logger;
    }
    void SetLogToTerminal(bool logToTerminal);
    bool GetLogTominal()const;

    void SetLogToLogFile(bool logToLogFile);
    bool GetLogToLogFile()const;
    void SetLogFile(const std::string& logFileName="dsf.log");


    void SetLogLevel(LOG_LEVEL level);
    LOG_LEVEL GetLogLevel()const;

    void operator+=(const Message&msg)
    {
        if(m_LoToTerminal)
        {
            //打印到终端里面，需要带颜色
            std::cout<<msg.Tostring(true)<<std::endl;
        }
        if(m_LogToLogFile)
        {
            //打印到文件里面，不需要带颜色
            m_logFile<<msg.Tostring(false)<<std::endl;
        }
        if(msg.Tostring().find("FATAL")!=std::string::npos)
        {
            std::cout<<"fatal happend!"<<std::endl;
            exit(-1);
        }
    }
};


#endif
//宏定义换行的时候，一定要加上‘\’
#define LOG(level)\
    if(level>=Logger::GetInstance()->GetLogLevel())\
        *Logger::GetInstance()+=Message(level,__FILE__,__FUNCTION__,__LINE__)

#define LOG_INFO LOG(INFO)
#define LOG_ERROR LOG(ERROR)
#define LOG_DEBUG LOG(DEBUG)
//上边的日志级别直接打印就好，但是fatal除了打印之外，程序必须结束
#define LOG_FATAL LOG(FATAL)


// int main()
// {
//     LOG_INFO<<"hello world";//与下等价
//     // 日志级别必须合法
//     if(INFO>=Logger::GetInstance()->GetLogLevel())
//     //         将消息拼接起来，看看要打印在哪里，有颜色就打印在终端，没颜色就打印在文件中
//         *Logger::GetInstance()+=Message(INFO,__FILE__,__FUNCTION__,__LINE__)<<"hello";
//          //                      消息头                                       消息体
// }